<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>滚动计数器</title>
		<script src="https://unpkg.com/vue@next"></script>
		<style>
			:root {
				font-family: Helvetica;
			}
			#root {
				min-height: 100vh;
				display: flex;
				justify-content: center;
				align-items: center;
			}
			.countbox {
				display: flex;
				position: relative;
				width: 200px;
				height: 50px;
				background-color: black;
				border-radius: 8px;
				text-align: center;
				justify-content: space-between;
				padding: 24px 8px;
				overflow: hidden;
				font-size: 36px;
				color: #fff;
				box-shadow: 0px 3px 12px rgb(0 0 0 / 20%);
			}

			.countbox::after {
				content: "";
				position: absolute;
				left: 0;
				right: 0;
				top: 0;
				bottom: 0;
				background: linear-gradient(
					180deg,
					rgba(0, 0, 0, 0.9) 0%,
					rgba(0, 0, 0, 0) 30%,
					rgba(0, 0, 0, 0) 70%,
					rgba(0, 0, 0, 0.9) 100%
				);
			}
			.countbox button {
				display: block;
				border: none;
				outline: none;
				background: none;
				font-size: 36px;
				color: #fff;
				cursor: pointer;
				z-index: 100;
			}
			.countbox span {
				display: block;
				line-height: 50px;
				transform: translateY(-50px);
			}
			.countbox span.before {
				transform: translateY(0);
				transition: transform 0.2s ease-in-out;
			}
			.countbox span.after {
				transform: translateY(-100px);
				transition: transform 0.2s ease-in-out;
			}
			.countbox span::before {
				display: block;
				content: attr(data-before);
			}
			.countbox span::after {
				display: block;
				content: attr(data-after);
			}
			.notebox {
				margin: 100px;
				border: 2px solid black;
				padding: 15px;
			}
			.notebox h3 {
				margin: 0;
			}
			.notebox p {
				padding-bottom: 3px;
				border-bottom: 1px solid gray;
			}
		</style>
	</head>
	<body>
		<div id="root">
			<div class="countbox">
				<button @click="sub">-</button>
				<span
					:class="{before: isBefore, after: isAfter}"
					:data-before="countBefore"
					:data-after="countAfter"
					ref="number"
					>{{count}}</span
				>
				<button @click="add">+</button>
			</div>
			<div class="notebox">
				<h3>滚动计数器</h3>
				<p>1.使用span::after，span::before显示下一个/上一个数字</p>
				<p>
					2.给span设置行高，transform:translateY(-1*行高)即可让中间的数字居中显示。-0*行高时，能显示上一个数字，-2*行高，显示下一个数字
				</p>
				<p>
					3.给span设置自定义属性:data-before和:data-after。然后在css里
					通过attr(data-before)获取值
				</p>
				<p>
					4.点击加减按钮时，改变translatrY的值，然后监听transitionend事件，过渡结束后，再改变数字的值。
				</p>
			</div>
		</div>
		<script>
			const app = Vue.createApp({
				data() {
					return {
						count: 0,
						isBefore: false,
						isAfter: false,
					}
				},
				computed: {
					countBefore() {
						return this.count - 1
					},
					countAfter() {
						return this.count + 1
					},
				},
				methods: {
					add() {
						this.isAfter = true
					},
					sub() {
						this.isBefore = true
					},
				},
				mounted() {
					this.$refs.number.addEventListener("transitionend", () => {
						if (this.isBefore) {
							this.count--
							this.isBefore = false
						}
						if (this.isAfter) {
							this.count += 1
							this.isAfter = false
						}
					})
				},
			})
			const vm = app.mount("#root")
		</script>
	</body>
</html>
